﻿using System;
using System.Collections.Generic;
using System.Text;

namespace igather.Framework
{
    /// <summary>
    /// Describes a link between two nodes
    /// </summary>
    public class Edge
    {
        private double mWeight;

        /// <summary>
        /// The weight of this edge
        /// </summary>
        public double Weight
        {
            get { return mWeight; }
            set
            {
                if ((value <= 0) || (value > 1))
				{
					Console.WriteLine("Um erro ocorreu ao tentar atribiur o peso de uma aresta.");
					Console.WriteLine("As pontas da aresta eram os nodos: {0} e {1}", Head.Name, Tail.Name);
                    throw new ArgumentOutOfRangeException("value", "Weight must be contained on an interval of (0;1]");
				}

                mWeight = value;
            }
        }

        private Vertex mHead;

        /// <summary>
        /// The head vertex of this arc
        /// </summary>
        public Vertex Head
        {
            get { return mHead; }
        }

        private Vertex mTail;

        /// <summary>
        /// The tail vertex of this arc
        /// </summary>
        public Vertex Tail
        {
            get { return mTail; }
        }

        /// <summary>
        /// True if edge is directed, otherwise false
        /// </summary>
        public bool IsDirected { get; private set; }

        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="directed">True if edge is directed, otherwise false</param>
        /// <param name="head">Head vertex of this edge</param>
        /// <param name="tail">Tail vertex of this edge</param>
        internal Edge(bool directed, Vertex head, Vertex tail, double weight)
        {
            IsDirected = directed;
            mHead = head;
            mTail = tail;
            mWeight = weight;
        }

        /// <summary>
        /// Overrides default comparison
        /// </summary>
        /// <param name="obj">Object to compare with</param>
        /// <returns>True if objects are equal, otherwise false</returns>
        public override bool Equals(object obj)
        {
            bool equals = false;
            Edge e = obj as Edge;
            if (e != null)
            {
                equals = (Head.Equals(e.Head)) && (Tail.Equals(e.Tail));
                if (!IsDirected)
                    equals |= (Head.Equals(e.Tail)) && (Tail.Equals(e.Head));
            }

            return equals;
        }

        /// <summary>
        /// Overrides default hash
        /// </summary>
        /// <returns>Hash code for this object</returns>
        public override int GetHashCode()
        {
            return Head.GetHashCode() | Tail.GetHashCode();
        }
    }
}
